package com.tinem.platform.service.task.consumer.redis;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import redis.clients.jedis.*;

import javax.annotation.Resource;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

/**
 * 清理redis
 */
@Slf4j
//@Service
public class ClearRedis implements ApplicationRunner {
    @Resource
    JedisConnectionFactory jedisConnectionFactory;

    public void exec(){
        Set<HostAndPort> node =  jedisConnectionFactory.getClusterConfiguration().getClusterNodes()
                        .stream().map(n->new HostAndPort(n.getHost(),n.getPort())).collect(Collectors.toSet());
        JedisCluster jedisCluster = new JedisCluster(node);
        delKey(jedisCluster,"platform:id:uuid:*");
        delKey(jedisCluster,"platform:uuid:id:*");
        delKey(jedisCluster,"platform:gateway:req:info:*");

    }
    public void delKey(JedisCluster jedisCluster,String key){
        AtomicLong atomicLong = new AtomicLong();
        jedisCluster.getClusterNodes().values().forEach(n->{
            try (Jedis jedis = n.getResource()){
                log.info("start:{},node:{}:{}",key,jedis.getClient().getHost(),jedis.getClient().getPort());
                String cursor = ScanParams.SCAN_POINTER_START;
                while (true){
                    ScanParams scanParams = new ScanParams();
                    scanParams.match(key);
                    scanParams.count(100);
                    ScanResult<String> scanResult = jedis.scan(cursor,scanParams);
                    scanResult.getResult().parallelStream().filter(k-> {
                                Long t = jedisCluster.ttl(k);
                                if (t==-1||t > 259200) {
                                    log.debug("del key:{},ttl:{}",k,t);
                                    return true;
                                }
                                return false;
                            }
                    ).forEach(k->{
                        jedisCluster.del(k);
                        atomicLong.incrementAndGet();
                    });

                    cursor = scanResult.getStringCursor();
                    if(StrUtil.isEmpty(cursor) || cursor.equals("0")){
                        break;
                    }
                    log.info("start:{},cursor:{}",key,cursor);
                }
            }
        });
        log.info("key:{},del:{}",key,atomicLong.get());
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        Thread t = new Thread(()->{
            exec();
        });
        t.setName("ClearRedis");
        t.start();
    }
}
